﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LightCAD.MathLib
{
    public class EllipsoidSurface3d : Surface3d
    {
        public Vector3 Origin { get; private set; }

        public double ARadius { get; private set; }
        public double BRadius { get; private set; }
        public double CRadius { get; private set; }
        public double StartAngle { get; private set; }
        public double EndAngle { get; private set; }
        public int RadialSegments { get; private set; }

        public EllipsoidSurface3d(Vector3 origin, double aRadius , double bRadius , double cRadius,double startAngle, double endAngle, int radialSegments = 32)
        {
            Ellipse3d ellipse = new Ellipse3d();
            this.Origin = origin;
            this.ARadius = aRadius; 
            this.BRadius=bRadius; 
            this.CRadius = cRadius;
            this.StartAngle = startAngle;
            this.EndAngle = endAngle;
            this.RadialSegments = radialSegments;
        }
        public override Tuple<double[], int[]> Trianglate()
        {
            var allPoints = new ListEx<Vector3>();
            var indices = new ListEx<int>();
            var abPoints = new List<Vector3>();
            var acPoints = new List<Vector3>();
            var bcPoints = new List<Vector3>();
            var acEl = new Ellipse3d();
            acEl.Center = Origin;
            acEl.StartAngle = this.StartAngle;
            acEl.EndAngle = this.EndAngle;
            acEl.RadiusX = this.ARadius;
            acEl.RadiusY = this.CRadius;
            acEl.Normal = new Vector3(0,-1,0);
            var acPs = acEl.GetPoints(RadialSegments);
            for(var i=0;i< acPs.Count;i++)
            {
                var cur = acPs[i];
                var na = cur.DistanceTo(Origin);
                var normal = cur.Clone().Sub(Origin).Normalize();
                var el= new Ellipse3d();
                el.Center = Origin;
                el.RadiusX = na;
                el.RadiusY = this.BRadius;
                el.StartAngle = - Utils.HalfPI;
                el.EndAngle = Utils.HalfPI;
                el.Normal = normal.Cross(new Vector3(0,1,0));
                var curPs = el.GetPoints(RadialSegments);
                if (i>0)
                {
                    var count = allPoints.Count;
                    for (var k = 1; k < curPs.Count; k++)
                    {
                        indices.Push(count - RadialSegments - 1 + k -1, count - RadialSegments - 1 + k , count+k-1);
                        indices.Push(count - RadialSegments - 1 + k, count + k,count + k - 1);
                    }
                }
                allPoints.AddRange(curPs);
            }
            var str = string.Join("|", allPoints.Select(n=>n.X.ToString("F4")+","+ n.Y.ToString("F4") + ","+ n.Z.ToString("F4")));
            var posArr = Utils.GenerateVertexArr(allPoints);
            return new Tuple<double[], int[]>(posArr, indices.ToArray());
        }
    }
}
